Skip to content

Fail merged apps with conflicting schema names - #139

Merged
owjs3901 merged 1 commit into
mainfrom
owjs3901/vespera-schema-collision
Aug 30, 2026
Merged

Fail merged apps with conflicting schema names#139
owjs3901 merged 1 commit into
mainfrom
owjs3901/vespera-schema-collision

Conversation

@owjs3901

Copy link
Copy Markdown
Contributor

Summary

  • reject differently-shaped component schemas that share a name while exported apps are merged
  • reuse CollectedMetadata::check_duplicate_schema_names() so identical definitions retain the existing silent deduplication behavior
  • identify the parent/merged app origins in the diagnostic and span the error to the incoming app path in merge = [...]

Verified pre-change behavior

The pre-change behavior was silent first-wins, not last-wins. OpenApi::merge preserves the schema already present in self; compile-time app assembly starts with the parent spec and folds merged apps in declaration order. Therefore the parent wins over children, and among children the earlier entry wins over a later collision.

I verified this against the existing vespera_core merge contract before changing the macro. In the reported reproduction, Plugin A was merged before Plugin B, so both /api/example/items/ and /memo/collision-probe remained in paths, but components.schemas.ExampleItem retained only Plugin A's { id, name, description, createdAt } shape. Plugin B's runtime response { collisionMarker, count } was silently documented with Plugin A's incompatible schema.

The merge boundary only has each exported app's OpenAPI sidecar and the syn::Path entries supplied to vespera!(merge = [...]); original struct spans from child crates are no longer available. The diagnostic therefore points at the conflicting incoming app path and names both best-available origins (for example, plugin_a::PluginA and plugin_b::PluginB).

Tests

  • cargo test --workspace
  • bun run lint
  • regression coverage for conflicting child schemas, identical shared schemas, and a schema defined once

The changepack records this as a minor vespera_macro change because previously silent collisions can now fail existing builds.

@github-actions

Copy link
Copy Markdown

Changepacks

vespera@0.3.1 - Cargo.toml

Maybe you forgot to write the following files to the latest version

vespera@0.3.1 → 0.3.2 - crates/vespera/Cargo.toml

Patch

  • Auto-update: depends on 'vespera_macro' via a local workspace dependency

vespera_macro@0.3.1 → 0.4.0 - crates/vespera_macro/Cargo.toml

Minor

  • Fail the build when merged apps define conflicting same-named OpenAPI schemas, turning a previously silent first-wins condition into an actionable compile error while preserving identical-schema deduplication.

@owjs3901
owjs3901 merged commit e7d8c78 into main Aug 30, 2026
9 checks passed
@owjs3901
owjs3901 deleted the owjs3901/vespera-schema-collision branch August 30, 2026 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant